home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / info-service / gopher / Rice_CMS / gopher24 / gopclisx.$rexx < prev    next >
Encoding:
Text File  |  1993-01-25  |  22.9 KB  |  291 lines

  1. /*                                                                      00010000
  2.  *        Name: GOPCLISX REXX                                           00020000
  3.  *              CMS Gopher client TCP/IP (sockets; "sox") function      00030000
  4.  *      Author: Rick Troth, Rice University, Information Systems        00040000
  5.  *        Date: 1992-Dec-23                                             00050000
  6.  *                                                                      00060000
  7.  *       Input: one or more gopher menu lines                           00070000
  8.  *    Output 0: zero or more blocks of raw (may be ASCII) data          00080000
  9.  *    Output 1: status messages and/or error messages                   00090000
  10.  *                                                                      00100000
  11.  *        Note: input is "plain text" (EBCDIC),  while output           00110000
  12.  *              may be anything.   If output is "plain text" (ASCII),   00120000
  13.  *              the following stage must handle translation.            00130000
  14.  */                                                                     00140000
  15.                                                                         00150000
  16. /*                                                                      00160000
  17.  *      Copyright 1992 Richard M. Troth.   This software was developed  00170000
  18.  *      with resources provided by Rice University and is intended      00180000
  19.  *      to serve Rice's user community.   Rice has benefitted greatly   00190000
  20.  *      from the free distribution of software,  therefore distribution 00200000
  21.  *      of unmodified copies of this material is not restricted.        00210000
  22.  *      You may change your own copy as needed.   Neither Rice          00220000
  23.  *      University nor any of its employees or students shall be held   00230000
  24.  *      liable for damages resulting from the use of this software.     00240000
  25.  */                                                                     00250000
  26.                                                                         00260000
  27. Trace "OFF"                                                             00270000
  28.                                                                         00280000
  29. /*  sync with input so that 'CALLPIPE COMMAND' will work  */            00290000
  30. 'PEEKTO'                                                                00300000
  31.                                                                         00310000
  32. 'CALLPIPE COMMAND GLOBALV SELECT GOPHER GET GOPHER'                     00320000
  33. If gopher = "" Then gopher = "Gopher"                                   00330000
  34. quit = 0                                                                00340000
  35.                                                                         00350000
  36. Parse Arg . '(' opts ')' .                                              00360000
  37.                                                                         00370000
  38. trans = 0                                                               00380000
  39. Do While opts ^= ""                                                     00390000
  40.     Parse Var opts op opts                                              00400000
  41.     Upper op                                                            00410000
  42.     Select  /*  op  */                                                  00420000
  43.         When Abbrev("TRANSLATE",op,4) Then trans = 1                    00430000
  44.         When Abbrev("NOTRANSLATE",op,6) Then trans = 0                  00440000
  45.         Otherwise Address "COMMAND" 'XMITMSG 3 OP (ERRMSG'              00450000
  46.         End  /*  Select  op  */                                         00460000
  47.     End  /*  Do  While  */                                              00470000
  48.                                                                         00480000
  49. If trans Then crlf = '0D25'x                                            00490000
  50.          Else crlf = '0D0A'x                                            00500000
  51.                                                                         00510000
  52. /*                                                                      00520000
  53.  *   Initialize RXSOCKET                                                00530000
  54.  */                                                                     00540000
  55. maxdesc = Socket('Initialize', gopher)                                  00550000
  56. If maxdesc = "-1" Then Do                                               00560000
  57.     If errno ^= "ESUBTASKALREADYACTIVE" Then Do                         00570000
  58.     /*  Call STATUS tcperror()  */                                      00580000
  59.         Exit -1                                                         00590000
  60.         End  /*  If  ..  Do  */                                         00600000
  61.     rc = Socket('Terminate')                                            00610000
  62.     maxdesc = Socket('Initialize', gopher)                              00620000
  63.     If maxdesc = "-1" Then Do                                           00630000
  64.         Call STATUS tcperror()                                          00640000
  65.         Exit -1                                                         00650000
  66.         End  /*  If  ..  Do  */                                         00660000
  67.     End  /*  If  ..  Do  */                                             00670000
  68.                                                                         00680000
  69. /*  L O O P  */                                                         00690000
  70.                                                                         00700000
  71. Do Forever                                                              00710000
  72.                                                                         00720000
  73.     'PEEKTO ITEM'                                                       00730000
  74.     If rc ^= 0 Then Leave                                               00740000
  75.                                                                         00750000
  76.     Parse Var item 1 type 2 name '05'x path '05'x host ,                00760000
  77.                                  '05'x port '05'x xtra                  00770000
  78.     port = Strip(port)              /*  for robustness  */              00780000
  79.     If type = '7' Then path = path || '05'x || xtra                     00790000
  80.                                                                         00800000
  81.     /*  Call STATUS "Connecting ... press ENTER twice to abort"  */     00810000
  82.     /*  Call STATUS "Connecting to" host "port" port  */                00820000
  83.     Call STATUS 22 '"' || host || '"' '"' || port || '"'                00830000
  84.                                                                         00840000
  85.     /*                                                                  00850000
  86.      *   Request a new socket descriptor (TCP protocol)                 00860000
  87.      */                                                                 00870000
  88.     socket = Socket('Socket', 'AF_INET', 'Sock_Stream')                 00880000
  89.     If socket = "-1" Then Do                                            00890000
  90.         Call STATUS tcperror()                                          00900000
  91.         Exit -1                                                         00910000
  92.         End  /*  If  ..  Do  */                                         00920000
  93.                                                                         00930000
  94.     If trans Then Do                                                    00940000
  95.         /*                                                              00950000
  96.          *   Enable ASCII<->EBCDIC Translation Option                   00960000
  97.          */                                                             00970000
  98.         rc = Socket('SetSockOpt', socket, 'SOL_SOCKET', 'SO_EBCDIC', 1) 00980000
  99.         If rc = "-1" Then Do                                            00990000
  100.             Call STATUS tcperror()                                      01000000
  101.             Exit -1                                                     01010000
  102.             End  /*  If  ..  Do  */                                     01020000
  103.         End  /*  If  ..  Do  */                                         01030000
  104.                                                                         01040000
  105.     /*                                                                  01050000
  106.      *   Connect to the server                                          01060000
  107.      */                                                                 01070000
  108.     Parse Var host h1 '.' h2 '.' h3 '.' h4 '.' .                        01080000
  109.     If  Datatype(h1,'N') &,                                             01090000
  110.         Datatype(h2,'N') &,                                             01100000
  111.         Datatype(h3,'N') &,                                             01110000
  112.         Datatype(h4,'N')    Then                                        01120000
  113.         hisaddr = d2c(h1) || d2c(h2) || d2c(h3) || d2c(h4)              01130000
  114.     Else Do                                                             01140000
  115.         hisaddr = Socket('GetHostByName', host)                         01150000
  116.         If hisaddr = "-1" Then Do                                       01160000
  117.         Call STATUS tcperror()                                          01170000
  118.             Exit -1                                                     01180000
  119.             End  /*  If  ..  Do  */                                     01190000
  120.         End  /*  Else  Do  */                                           01200000
  121.                                                                         01210000
  122.     /*  Parse Var hisaddr h1 +1 h2 +1 h3 +1 h4 +1 .  */                 01220000
  123.                                                                         01230000
  124.     name = AF_INET || Htons(port) || hisaddr                            01240000
  125.                                                                         01250000
  126.     /*                                                                  01260000
  127.      *   Set this socket to non-blocking mode                           01270000
  128.      */                                                                 01280000
  129.     rc = Socket('Ioctl', socket, 'FIONBIO', 1)                          01290000
  130.     If rc="-1" Then Do                                                  01300000
  131.         Call STATUS tcperror()                                          01310000
  132.         Exit -1                                                         01320000
  133.         End  /*  If  ..  Do  */                                         01330000
  134.                                                                         01340000
  135.     /*                                                                  01350000
  136.      *   Connect to the host                                            01360000
  137.      */                                                                 01370000
  138.     rc = Socket('Connect', socket, name)                                01380000
  139.     If rc = "-1" Then ,                                                 01390000
  140.         If errno ^= "EINPROGRESS" Then Do                               01400000
  141.             Call STATUS tcperror()                                      01410000
  142.             If errno = "ECONNREFUSED" Then ,                            01420000
  143.                 Call STATUS 23 '"' || host || '"' '"' || port || '"'    01430000
  144.         Exit -1                                                         01440000
  145.         End  /*  If  ..  Do  */                                         01450000
  146.                                                                         01460000
  147.     rc = FD_ZERO('readmask')                                            01470000
  148.     rc = FD_ZERO('writemask')                                           01480000
  149.     rc = FD_SET(socket,'writemask')                                     01490000
  150.     rc = FD_SET('0', 'readmask')                                        01500000
  151.                                                                         01510000
  152.     rc = Socket('Select', socket+1, 'readmask', 'writemask', 0, 20)     01520000
  153.     If rc="-1" Then Do                                                  01530000
  154.         Call STATUS tcperror()                                          01540000
  155.         Exit -1                                                         01550000
  156.         End  /*  If  ..  Do  */                                         01560000
  157.                                                                         01570000
  158.     If FD_ISSET('0', 'readmask')<>0 Then Do                             01580000
  159.         rc = Socket('Close', socket)                                    01590000
  160.         /*  Call STATUS "Connection canceled by user request"  */       01600000
  161.         Call STATUS 28                                                  01610000
  162.         Exit -1                                                         01620000
  163.         End                                                             01630000
  164.                                                                         01640000
  165.     If FD_ISSET(socket, 'writemask')=0 Then Do                          01650000
  166.         rc = Socket('Close', socket)                                    01660000
  167.         /*  Call STATUS "Connection canceled by TIMEOUT"  */            01670000
  168.         Call STATUS 29                                                  01680000
  169.         Exit -1                                                         01690000
  170.         end                                                             01700000
  171.                                                                         01710000
  172.     /* Return to standard mode                                          01720000
  173.     rc = Socket('Ioctl', socket, 'FIONBIO', 0)                          01730000
  174.      */                                                                 01740000
  175.                                                                         01750000
  176.     /*  TRANSlate option will affect both writing to,  as well as     * 01760000
  177.      *  reading from,  the socket.   So if the socket is set for      * 01770000
  178.      *  TRANSLATE,  then we need not translate the path from EBCDIC   * 01780000
  179.      *  to ASCII.   But if not,  then we must do so as follows:       */01790000
  180.     If ^trans Then                                                      01800000
  181.     'CALLPIPE VAR PATH | TCPE2A' gopher '| VAR PATH'                    01810000
  182.                                                                         01820000
  183.     /*                                                                  01830000
  184.      *   Send the "query" to the server                                 01840000
  185.      */                                                                 01850000
  186.     bytes_out = Socket('Write', socket, path || crlf)                   01860000
  187.     If bytes_out = "-1" Then Do                                         01870000
  188.         If errno = 'EPIPE' Then ,                                       01880000
  189.             'OUTPUT' "ECONNREFUSED"                                     01890000
  190.         If errno = 'EPIPE' Then ,                                       01900000
  191.             Call STATUS 23 '"' || host || '"' '"' || port || '"'        01910000
  192.         Else Call STATUS tcperror()                                     01920000
  193.         Exit -1                                                         01930000
  194.         End  /*  If  ..  Do  */                                         01940000
  195.                                                                         01950000
  196.     /*  Call STATUS "Reading ... press ENTER twice to abort"  */        01960000
  197.     /*  Call STATUS "Reading ... "  */                                  01970000
  198.     /*  Call STATUS 24  */                                              01980000
  199.                                                                         01990000
  200.     totbytes = 0                                                        02000000
  201. prevtot = 0                                                             02010000
  202.     /*                                                                  02020000
  203.      *   Loop, reading response and sending to the next pipeline stage  02030000
  204.      */                                                                 02040000
  205.     Do Forever                                                          02050000
  206.         /* Set up to trap console ENTER key */                          02060000
  207.         rc = FD_ZERO('readmask')                                        02070000
  208.         rc = FD_SET('0','readmask')                                     02080000
  209.         rc = FD_SET(socket,'readmask')                                  02090000
  210.                                                                         02100000
  211.         /* Wait for something to happen */                              02110000
  212.         rc = Socket('Select',socket+1,'readmask',0,0)                   02120000
  213.         /* If console input, clear 'socket' and return */               02130000
  214.         If FD_ISSET('0','readmask')<>0 Then Do                          02140000
  215.             /*  Call STATUS "Request ABORTED"  */                       02150000
  216.             Call STATUS 27                                              02160000
  217.             rc = Socket('Close', socket)                                02170000
  218.             Leave                                                       02180000
  219.             End                                                         02190000
  220.                                                                         02200000
  221.         bytes_in = Socket('Read', socket, 'pack')                       02210000
  222.         If bytes_in = "-1" Then                                         02220000
  223.             Call STATUS tcperror()                                      02230000
  224.         If bytes_in < 1 Then Leave                                      02240000
  225.                                                                         02250000
  226.         totbytes = totbytes + bytes_in                                  02260000
  227. If prevtot/totbytes < 0.9 Then  /* adjust the 0.9 factor to taste */    02270000
  228. Do                                                                      02280000
  229.         Call STATUS 26 '"' || totbytes || '"'                           02290000
  230. prevtot = totbytes                                                      02300000
  231. End                                                                     02310000
  232.         'OUTPUT' pack                                                   02320000
  233.         If rc ^= 0 Then Leave                                           02330000
  234.                                                                         02340000
  235.         End  /*  Do  Forever  */                                        02350000
  236.                                                                         02360000
  237.     If rc ^= 0 Then Leave                                               02370000
  238.                                                                         02380000
  239.     /*                                                                  02390000
  240.      *   All done, relinquish our socket descriptor                     02400000
  241.      */                                                                 02410000
  242.     rc = Socket('Close', socket)                                        02420000
  243.     If rc = "-1" Then Do                                                02430000
  244.         Call STATUS tcperror()                                          02440000
  245.         Leave                                                           02450000
  246.         End  /*  If  ..  Do  */                                         02460000
  247.                                                                         02470000
  248.     'READTO'                                                            02480000
  249.                                                                         02490000
  250.     End  /*  Do  Forever  */                                            02500000
  251.                                                                         02510000
  252. /*                                                                      02520000
  253.  *   Tell RXSOCKET that we are done with this IUCV path                 02530000
  254.  */                                                                     02540000
  255. rc = Socket('Terminate')                                                02550000
  256. If rc = "-1" Then Do                                                    02560000
  257.     Call STATUS tcperror()                                              02570000
  258.     Exit -1                                                             02580000
  259.     End                                                                 02590000
  260.                                                                         02600000
  261. /*  an empty line as last in status stream indicates success  */        02610000
  262. /*  Call STATUS " "  */                                                 02620000
  263.                                                                         02630000
  264. Exit                                                                    02640000
  265.                                                                         02650000
  266.                                                                         02660000
  267.                                                                         02670000
  268. /* -------------------------------------------------------------- STATUS02680000
  269.  * Write  "status messages"  to the secondary stream,  if connected.    02690000
  270.  * This routine saves & restores the current stream selection.          02700000
  271.  * (though there are presently no other streams used besides 1 and 0)   02710000
  272.  */                                                                     02720000
  273. STATUS:   Procedure                                                     02730000
  274. Parse Arg string                                                        02740000
  275.                                                                         02750000
  276. /* note the current stream (should be zero) */                          02760000
  277. 'STREAMNO OUTPUT'                                                       02770000
  278. If rc < 0 Then Return                                                   02780000
  279. stream = rc                                                             02790000
  280.                                                                         02800000
  281. /* select secondary stream and output the string */                     02810000
  282. 'SELECT OUTPUT 1'                                                       02820000
  283. If rc ^= 0 Then Return                                                  02830000
  284. If Datatype(Word(string,1),'N') Then                                    02840000
  285. 'CALLPIPE COMMAND XMITMSG' string '(APPLID GOP CALLER TCP ERRMSG | *:'  02850000
  286. Else 'OUTPUT' string                                                    02860000
  287. 'SELECT OUTPUT' stream                                                  02870000
  288.                                                                         02880000
  289. Return                                                                  02890000
  290.                                                                         02900000
  291.